using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class FunctionModule : Singleton<FunctionModule>
    {
        private List<int> waitingShows = new(8);
        private List<int> showings = new(8);
        private bool isStartShowing = false;

        private FunctionModule() { }

        public void InitModule()
        {
            ManagerCenter.MonoDriver.updateEvent += OnUpdate;
        }

        public void ClearModule()
        {
            ManagerCenter.MonoDriver.updateEvent -= OnUpdate;
            waitingShows.Clear();
            showings.Clear();
        }

        private void OnUpdate(float deltaTime, float unscaledDeltaTime)
        {
            if (isStartShowing || !IsCanShowing())
                return;
            CheckShowUI();
        }

        public void JugdeShowingWhenFunctionTypeOn(int functionTypeId)
        {
            var cfg = TableCenter.functionType.Get(functionTypeId);
            if (cfg == null)
                return;

            if (cfg.IsShow)
            {
                if (!TryAddShowings(functionTypeId))
                    waitingShows.Add(functionTypeId);
            }

            CheckWaitingShows();
            SortingShowing();
            CheckShowUI();
        }

        private bool TryAddShowings(int functionTypeId)
        {
            var cfg = TableCenter.functionType.Get(functionTypeId);
            bool isCanShow = cfg.PreFunctionType <= 0 || GameDataCenter.PlayerData.functionTypes.Contains(cfg.PreFunctionType);
            if (isCanShow)
                showings.Add(functionTypeId);
            return isCanShow;
        }

        private void CheckWaitingShows()
        {
            if (waitingShows.Count < 1)
                return;
            for (int i = waitingShows.Count - 1; i >= 0; i--)
            {
                if (TryAddShowings(waitingShows[i]))
                    waitingShows.RemoveAt(i);
            }
        }

        private void SortingShowing()
        {
            if (showings.Count < 2)
                return;
            showings.Sort();
        }

        private void CheckShowUI()
        {
            if (!IsCanShowing())
            {
                isStartShowing = false;
                return;
            }
            isStartShowing = true;
            if (!ManagerCenter.UI.IsWindowShowing<UIFunctionOn>())
            {
                ViewUI().Forget();
            }
        }

        private bool IsCanShowing()
        {
            return CheckIsArea(GameplayAreaType.MainCity) && CheckIsInMainUI() && showings.Count > 0;
        }

        private bool CheckIsArea(GameplayAreaType areaType)
        {
            return GameDataCenter.CurrGameArea == areaType;
        }

        private bool CheckIsInMainUI()
        {
            return ManagerCenter.UI.IsMainWindowTopShowing();
        }

        private async UniTaskVoid ViewUI()
        {
            await ManagerCenter.UI.ShowWindowAsync<UIFunctionOn>(UD_FunctionOn.Create(showings[0], OnCallWhenUIClose));
            showings.RemoveAt(0);
        }

        private void OnCallWhenUIClose()
        {
            CheckShowUI();
        }

        static public bool CheckIsOpenAndTip(FunctionType functionType)
        {
            bool isOpen = IsOpen(functionType);
            if (!isOpen)
            {
                var cfg = TableCenter.functionType.Get((int)functionType);
                if (cfg != null)
                    NoticeModule.ShowNoticeNoCall(NoticeConstant.ID_CommonFloat, cfg.LockNotice);
            }
            return isOpen;
        }

        static public bool IsOpen(FunctionType functionType)
        {
            return IsOpen((int)functionType);
        }

        static bool IsOpen(int functionCfgId)
        {
            if (functionCfgId == 0)
                return true;
            var cfg = TableCenter.functionType.Get(functionCfgId);
            if (cfg == null)
                return false;
            var functionTypes = GameDataCenter.PlayerData?.functionTypes;
            if (functionTypes == null || !functionTypes.Contains(functionCfgId) || (cfg.PreFunctionType > 0 && !functionTypes.Contains(cfg.PreFunctionType)))
                return false;
            return true;
        }


    }
}
